﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MsTestUtilities;
using MsTestUtilities.Utilities;

namespace MsTestUtilitiesTests.ExceptionExpectationTests
{
    [TestClass]
    public class ThrowsTests
    {
        private ExceptionExpectation<InvalidOperationException> _expector;

        [TestInitialize]
        public void Setup()
        {
            _expector = new ExceptionExpectation<InvalidOperationException>();
        }

        [TestMethod]        
        public void NoExceptionThrown_FailAssertion()
        {
            var result = _expector.IsSatisfiedFor(() => { });
            AssertAssertionError("Expected exception <InvalidOperationException>. No excpetion was thrown.", result);
        }

        [TestMethod]
        public void ExpectedExceptionThrown_PassAssertion()
        {
            var result = _expector.IsSatisfiedFor(() => { throw new InvalidOperationException(); });
            Assert.IsTrue(result.AssertionHolds);
        }

        [TestMethod]
        public void WrongExceptionThrown_FailAssertion()
        {
            var result = _expector.IsSatisfiedFor(() => { throw new IndexOutOfRangeException(); });
            AssertAssertionError("Expected exception <InvalidOperationException>. Actual <IndexOutOfRangeException>.", result);
        }

        [TestMethod]
        public void ParentExceptionThrown_FailAssertion()
        {
            var result = _expector.IsSatisfiedFor(() => { throw new Exception(); });
            AssertAssertionError("Expected exception <InvalidOperationException>. Actual <Exception>.", result);
        }

        private void AssertAssertionError(string expectedMessage, AssertionResult result)
        {
            Assert.IsFalse(result.AssertionHolds);
            Assert.AreEqual(expectedMessage, result.AssertionError);
        }
    }
}
